/*
 * @Author: wrngygy
 * @Date: 2025-07-01
 * @Description: Vue 3 媒体查询 Composable 函数
 */

import { ref, onMounted, onUnmounted, computed } from 'vue'

/**
 * 媒体查询 Hook
 * @param query 媒体查询字符串
 * @returns 是否匹配的响应式引用
 */
export function useMediaQuery(query: string) {
	const matches = ref(false)
	let mediaQuery: MediaQueryList | null = null

	const updateMatches = () => {
		if (mediaQuery) {
			matches.value = mediaQuery.matches
		}
	}

	onMounted(() => {
		if (typeof window !== 'undefined') {
			mediaQuery = window.matchMedia(query)
			matches.value = mediaQuery.matches
			
			// 监听变化
			if (mediaQuery.addEventListener) {
				mediaQuery.addEventListener('change', updateMatches)
			} else {
				// 兼容旧版本浏览器
				mediaQuery.addListener(updateMatches)
			}
		}
	})

	onUnmounted(() => {
		if (mediaQuery) {
			if (mediaQuery.removeEventListener) {
				mediaQuery.removeEventListener('change', updateMatches)
			} else {
				// 兼容旧版本浏览器
				mediaQuery.removeListener(updateMatches)
			}
		}
	})

	return matches
}

/**
 * 屏幕尺寸 Hook
 * @returns 屏幕尺寸相关的响应式数据
 */
export function useScreenSize() {
	const width = ref(0)
	const height = ref(0)

	const updateSize = () => {
		width.value = window.innerWidth
		height.value = window.innerHeight
	}

	onMounted(() => {
		if (typeof window !== 'undefined') {
			updateSize()
			window.addEventListener('resize', updateSize)
		}
	})

	onUnmounted(() => {
		if (typeof window !== 'undefined') {
			window.removeEventListener('resize', updateSize)
		}
	})

	return {
		width,
		height,
		// 计算属性
		aspectRatio: computed(() => width.value / height.value),
		isLandscape: computed(() => width.value > height.value),
		isPortrait: computed(() => width.value <= height.value)
	}
}

/**
 * 响应式断点 Hook
 * @returns 各种断点的响应式状态
 */
export function useBreakpoints() {
	// 常用断点定义
	const breakpoints = {
		xs: 480,
		sm: 768,
		md: 1024,
		lg: 1200,
		xl: 1920
	}

	const { width } = useScreenSize()

	return {
		// 当前屏幕宽度
		width,
		
		// 断点判断
		isXs: computed(() => width.value < breakpoints.xs),
		isSm: computed(() => width.value >= breakpoints.xs && width.value < breakpoints.sm),
		isMd: computed(() => width.value >= breakpoints.sm && width.value < breakpoints.md),
		isLg: computed(() => width.value >= breakpoints.md && width.value < breakpoints.lg),
		isXl: computed(() => width.value >= breakpoints.lg),
		
		// 范围判断
		isMobile: computed(() => width.value < breakpoints.sm),
		isTablet: computed(() => width.value >= breakpoints.sm && width.value < breakpoints.md),
		isDesktop: computed(() => width.value >= breakpoints.md),
		
		// 最小宽度判断
		isXsUp: computed(() => width.value >= breakpoints.xs),
		isSmUp: computed(() => width.value >= breakpoints.sm),
		isMdUp: computed(() => width.value >= breakpoints.md),
		isLgUp: computed(() => width.value >= breakpoints.lg),
		isXlUp: computed(() => width.value >= breakpoints.xl),
		
		// 最大宽度判断
		isXsDown: computed(() => width.value < breakpoints.xs),
		isSmDown: computed(() => width.value < breakpoints.sm),
		isMdDown: computed(() => width.value < breakpoints.md),
		isLgDown: computed(() => width.value < breakpoints.lg),
		isXlDown: computed(() => width.value < breakpoints.xl),
		
		// 设备类型
		deviceType: computed(() => {
			if (width.value < breakpoints.xs) return 'xs'
			if (width.value < breakpoints.sm) return 'sm'
			if (width.value < breakpoints.md) return 'md'
			if (width.value < breakpoints.lg) return 'lg'
			return 'xl'
		}),
		
		// 断点配置
		breakpoints
	}
}

/**
 * 设备特性检测 Hook
 * @returns 设备特性的响应式状态
 */
export function useDeviceFeatures() {
	// 媒体查询检测
	const isDarkMode = useMediaQuery('(prefers-color-scheme: dark)')
	const isReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)')
	const isHighContrast = useMediaQuery('(prefers-contrast: high)')
	const isRetina = useMediaQuery('(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)')
	const isTouchDevice = useMediaQuery('(hover: none) and (pointer: coarse)')
	const canHover = useMediaQuery('(hover: hover)')
	
	// 屏幕方向
	const isLandscape = useMediaQuery('(orientation: landscape)')
	const isPortrait = useMediaQuery('(orientation: portrait)')

	return {
		// 用户偏好
		isDarkMode,
		isReducedMotion,
		isHighContrast,
		
		// 设备能力
		isRetina,
		isTouchDevice,
		canHover,
		
		// 屏幕方向
		isLandscape,
		isPortrait,
		
		// 浏览器特性检测
		supportsTouchEvents: computed(() => 'ontouchstart' in window),
		supportsPointerEvents: computed(() => 'onpointerdown' in window),
		supportsPassiveEvents: computed(() => {
			let supportsPassive = false
			try {
				const opts = Object.defineProperty({}, 'passive', {
					get() {
						supportsPassive = true
						return true
					}
				})
				window.addEventListener('testPassive', () => {}, opts)
				window.removeEventListener('testPassive', () => {}, opts)
			} catch (e) {
				// 忽略错误
			}
			return supportsPassive
		})
	}
}

/**
 * 响应式组件尺寸 Hook
 * @param elementRef 元素引用
 * @returns 元素尺寸的响应式数据
 */
export function useElementSize(elementRef: any) {
	const width = ref(0)
	const height = ref(0)
	let resizeObserver: ResizeObserver | null = null

	const updateSize = (entries: ResizeObserverEntry[]) => {
		const entry = entries[0]
		if (entry) {
			width.value = entry.contentRect.width
			height.value = entry.contentRect.height
		}
	}

	onMounted(() => {
		if (elementRef.value && window.ResizeObserver) {
			resizeObserver = new ResizeObserver(updateSize)
			resizeObserver.observe(elementRef.value)
		}
	})

	onUnmounted(() => {
		if (resizeObserver) {
			resizeObserver.disconnect()
		}
	})

	return {
		width,
		height,
		aspectRatio: computed(() => width.value / height.value)
	}
}

/**
 * 容器查询模拟 Hook
 * @param containerRef 容器元素引用
 * @param breakpoints 断点配置
 * @returns 容器查询状态
 */
export function useContainerQuery(
	containerRef: any,
	breakpoints: Record<string, number> = { sm: 400, md: 600, lg: 800 }
) {
	const { width } = useElementSize(containerRef)

	const queries = computed(() => {
		const result: Record<string, boolean> = {}
		
		Object.entries(breakpoints).forEach(([key, value]) => {
			result[key] = width.value >= value
			result[`${key}Up`] = width.value >= value
			result[`${key}Down`] = width.value < value
		})
		
		return result
	})

	return {
		width,
		...queries.value,
		queries
	}
}
